package com.wyw.learning.handler;

import com.wyw.learning.bean.ResponseResult;
import com.wyw.learning.constant.OAuth2Constant;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Title
 * @Description
 *      重写AuthenticationEntryPoint接口的方法。
 *          如果异常是InsufficientAuthenticationException类型，则说明是访问了受保护的资源，但没带上令牌（token），然后根据请求头的accept信息判断请求来源，如果accept是"text/html"，则通过LoginUrlAuthenticationEntryPoint将请求跳转到“login”登录页，否则通过ResponseResult提示“需要带上令牌进行访问”。如果异常是InvalidBearerTokenException类型，则通过ResponseResult提示“令牌无效或已过期”。如果是其他异常类型，通过ResponseResult将原始异常信息输出。
 * @Author Mr Wu yewen.wu.china@gmail.com
 * @Date 2023/9/25 16:56
 * Update History:
 * Author        Time            Content
 */
public class MyAuthenticationEntryPoint implements AuthenticationEntryPoint {


    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {

        if(authException instanceof InsufficientAuthenticationException){
            String accept = request.getHeader("accept");
            if(accept.contains(MediaType.TEXT_HTML_VALUE)){
                //如果是html请求类型，则返回登录页
                LoginUrlAuthenticationEntryPoint loginUrlAuthenticationEntryPoint = new LoginUrlAuthenticationEntryPoint(OAuth2Constant.LOGIN_URL);
                loginUrlAuthenticationEntryPoint.commence(request,response,authException);
            }else {
                //如果是api请求类型，则返回json
                ResponseResult.exceptionResponse(response,"需要带上令牌进行访问");
            }
        }else if(authException instanceof InvalidBearerTokenException){
            ResponseResult.exceptionResponse(response,"令牌无效或已过期");
        }else{
            ResponseResult.exceptionResponse(response,authException);
        }

    }


}
